/**
 * Copyright(c) 2010 Ceno Techonologies Co., Ltd.
 *
 * History:
 *   15-1-6 下午2:56 Created by lyyang
 */
package com.jade.bss.security.shiro.authc;

import com.jade.bss.base.customer.Customer;
import com.jade.bss.base.customer.CustomerManager;
import com.jade.bss.customer.grant.GrantManager;
import com.jade.bss.customer.permission.PermissionEntry;
import com.jade.bss.customer.principal.SimplePrincipal;
import com.jade.framework.base.context.ApplicationContextUtils;
import com.jade.framework.cache.CacheService;
import com.jade.framework.cache.CacheUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.ArrayList;
import java.util.List;

/**
 * 用户通过用户名和密码登录
 *
 * @author <a href="mailto:lyyang@ceno.cn">lyyang</a>
 * @version 1.0 15-1-6 下午2:56
 */
public class CustomerRealm extends AuthorizingRealm
{
    private CustomerManager customerManager = ApplicationContextUtils.getBean("bss_customerManager");

    public CustomerRealm()
    {
        setAuthenticationTokenClass(CustomerPasswordToken.class);
    }

    public static final String CACHE_KEY_PERM = "security.perms";

    protected GrantManager grantManager = ApplicationContextUtils.getBean("bss_grantManager");
    protected String systemName = "nb-bss";
    protected CacheService cacheService = ApplicationContextUtils.getBean("system_cacheService");
    private long superManId = 1;

    public void setSuperManId(long superManId)
    {
        this.superManId = superManId;
    }

    public void setSystemName(String systemName)
    {
        this.systemName = systemName;
    }

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
    {
        Customer customer = (Customer) principalCollection.getPrimaryPrincipal();
        List<String> permissions = cacheService.get(CacheUtils.joinKey(systemName, CACHE_KEY_PERM, String.valueOf(customer.getId())));
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (permissions != null) {
            info.addStringPermissions(permissions);
        }
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException
    {
        CustomerPasswordToken token = (CustomerPasswordToken) authenticationToken;
        Customer customer = customerManager.getCustomer(token.getType(), token.getUsername());
        if (customer == null) {
            return null;
        }
        setPermissionToCache(customer);
        return new SimpleAuthenticationInfo(customer, customer.getPassword(), getName());
    }

    protected void setPermissionToCache(Customer customer)
    {
        List<String> permissions = getPermissions(customer);
        cacheService.set(CacheUtils.joinKey(systemName, CACHE_KEY_PERM, String.valueOf(customer.getId())), permissions,24 * 3600);
    }

    protected List<String> getPermissions(Customer account)
    {
        List<String> permissions = new ArrayList<String>();
        SimplePrincipal principal = new SimplePrincipal();
        principal.setName(String.valueOf(account.getId()));
        principal.setType(SimplePrincipal.TYPE_ROLE);
        List<PermissionEntry> perList = grantManager.getPermissions(principal);
        if (perList != null) {
            for (PermissionEntry perEntry : perList) {
                permissions.add(perEntry.getName());
            }
        }
        return permissions;
    }

    protected boolean isSuperman(PrincipalCollection principals)
    {
        Customer admin = (Customer) principals.getPrimaryPrincipal();
        return admin != null && admin.getId() == superManId;
    }
}
